package com.cskaoyan.javase.array._2memory;

/**
 * 什么是引用数据类型变量?
 * 数组是典型的引用数据类型,这里我们以数组的动态初始化为案例,了解引用数据类型
 *
 * 引用数据类型 = 引用 + 对象
 * 引用通过存储堆上对象的地址和对象产生联系
 * 对象是实质,但我们只能通过引用间接访问对象,无法直接访问对象
 *
 * 单独存在的基本数据类型的变量，必然是一个局部变量。
 * 数组或者对象中的基本数据类型元素,不能抛开对象单独存在
 *
 * @since 15:42
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo2 {
    public static void main(String[] args) {
        // 动态初始化一个长度为3的int数组
        /*
            arr是数组的名字,它在main方法中定义,实际上它是一个局部变量
            所以它需要手动进行初始化赋值后,才能够使用,这是局部变量的特点
            它被存储在JVM栈的main方法栈帧中

            重点来看右边的语句"new int[3]"
            new关键字表示在堆上创建一个新的,独立的数组对象
            这个数组对象,长度是3,而且是一个int数组

            以上,我们把处在栈上,数组的名字,局部变量,称之为"引用"
            也可以称之为"对象的引用"

            " = "的作用连接两边,表示"栈上的引用指向堆上的对象"

            怎么指向呢?
            引用通过存储堆上对象的内存地址,和堆上对象产生联系,指向堆上的对象

            对象名,引用中到底存储的是什么?
            是堆上对象的地址

         */
        int[] arr = new int[3];
        // System.out.println(arr);

        // 通过引用可以去访问堆上的对象
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        System.out.println(arr.length);

        // 直接输出数组名
        /*
            [I@1540e19d
            [表示这是一个数组,而且是一个一维数组
            I表示这个数组是int类型
            @表示地址
            1540e19d是一个十六进制数
            该十六进制数是底层根据一系列算法计算得出的一个值
            它计算的依据就是对象的内存地址
            所以普遍来说,可以把这个十六进制数看成对象的地址值
            所以:
                普遍来说,不同内存地址的对象,它们的地址值是不同的
         */
        System.out.println(arr);

        /*
            "=="连接引用数据类型,比较的是地址
            是引用中存储的指向堆上对象的内存地址
            返回true --> 完全指向同一个对象
            说白了,"=="比较引用数据类型,自己和自己相等,除此之外都不相等
         */
        int[] arr2 = {1, 2, 3};
        int[] arr3 = {4, 5, 6};
        System.out.println(arr2 == arr3);
    }
}
